#include <cstdio>
#include <cstdlib>
#include <cassert>
#include "gc.h"
#include <malloc.h>
//#include "tlpi_hdr.h"

struct mylist
{
	gc_ptr<mylist> next;
	int val;

	mylist ()
	{
		val = 0;
		next = 0;
	}

	mylist (int v)
	{
		val = v;
		next = 0;
	}

	~mylist ()
	{
		val = 0;
		next = 0;
	}

};

void add (gc_ptr<mylist> &head, gc_ptr<mylist> elem, gc_ptr<mylist> cur)
{
	if (cur == 0)
		head = elem;
	else 
	{
		if (cur->next == NULL)
			cur->next = elem;
		else
			add(head, elem, cur->next);
	}
}

void test (int STEP_COUNT, int ELEM_COUNT)
{
	for (int i = 0; i < STEP_COUNT; i++)
	{
//		scanf ("%*c");
		gc_ptr<mylist> head = 0;
		for (int j = 0; j < ELEM_COUNT; j++)
			add(head, new (gc_new <mylist>(1)) mylist, head);
//		scanf ("%*c");
//		printf ("head %p\n", head.ptr);
//		if (!(i % 100))
//		mark_and_sweep();
//		printf ("STEP END\n");
	}
}

void print (gc_ptr<mylist> cur)
{
	if (cur == 0)
		return;
	printf("%d\n", cur->val);
	print(cur->next);
}

int main (int argc, char *argv[])
{
	assert(argc == 3);
	int STEP_COUNT, ELEM_COUNT;

	sscanf (argv[1], "%d", &STEP_COUNT);
	sscanf (argv[2], "%d", &ELEM_COUNT);

	struct mallinfo mi;

	mi = mallinfo();
	printf ("START %i\n", mi.uordblks);

	test(STEP_COUNT, ELEM_COUNT);

	mi = mallinfo();
	printf ("1test %i\n", mi.uordblks);
	mark_and_sweep();
	
	mi = mallinfo();
	printf ("after m&s %i\n", mi.uordblks);

	test(STEP_COUNT, ELEM_COUNT);

	gc_ptr <mylist> head;
	for (int j = 0; j < 300; j++)
	{
		//gc_ptr<mylist> m = gc_new <mylist>(1);
		gc_ptr<mylist> m = new (gc_new <mylist>(1)) mylist(j);
		m->val = j;
		add(head, m, head);
	}
	//print (head);
	
	mi = mallinfo();
	printf ("2test %i\n", mi.uordblks);

	mark_and_sweep();
	//print (head);
	mi = mallinfo();
	printf ("after m&s %i\n", mi.uordblks);
	print(head);
	return 0;
}
